﻿using Sidvall.Serialization;
using System.Collections.Generic;

namespace Sidvall.Collections
{
    public static class EnumerableExtension
    {
        #region Add

        public static void Add(this System.Collections.IEnumerable items, object source)
        {
            var list1 = items as System.Collections.IList;
            if (list1 != null)
                list1.Add(source);
        }

        #endregion
        #region AddRange

        public static void AddRange(this System.Collections.IEnumerable items, System.Collections.IEnumerable source)
        {
            if (source == null)
                return;
            var list1 = items as System.Collections.IList;
            if (list1 != null)
            {
                foreach (var item in source)
                    list1.Add(item);
            }
        }
        public static void AddRange<TKey, TItem>(this Dictionary<TKey, TItem> items, IEnumerable<TItem> source, System.Func<TItem, TKey> getKeyHandler, bool removeDuplicates)
        {
            if (items == null)
                return;
            if (source == null)
                return;
            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            foreach (var item in source)
            {
                var key = getKeyHandler(item);
                if (key != null)
                {
                    if ((!removeDuplicates) || (!items.ContainsKey(key)))
                        items.Add(key, item);
                }
            }
        }
        public static void AddRange<TItem>(this Dictionary<string, TItem> items, IEnumerable<TItem> source, System.Func<TItem, string> getKeyHandler, bool removeDuplicates,
            bool ignoreWhiteSpaceKeys)
        {
            if (items == null)
                return;
            if (source == null)
                return;
            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            if (ignoreWhiteSpaceKeys)
            {
                foreach (var item in source)
                {
                    var key = getKeyHandler(item);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        key = key.Trim();
                        if ((!removeDuplicates) || (!items.ContainsKey(key)))
                            items.Add(key, item);
                    }
                }
            }
            else
            {
                foreach (var item in source)
                {
                    var key = getKeyHandler(item);
                    if (key != null)
                    {
                        if ((!removeDuplicates) || (!items.ContainsKey(key)))
                            items.Add(key, item);
                    }
                }
            }
        }
        public static void AddRange<TKey, TItem>(this HashSet<TKey> items, IEnumerable<TItem> source, System.Func<TItem, TKey> getKeyHandler, bool removeDuplicates)
        {
            if (items == null)
                return;
            if (source == null)
                return;
            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            foreach (var item in source)
            {
                var value = getKeyHandler(item);
                if (value != null)
                {
                    if ((!removeDuplicates) || (!items.Contains(value)))
                        items.Add(value);
                }
            }
        }
        public static void AddRange<TItem>(this HashSet<string> items, IEnumerable<TItem> source, System.Func<TItem, string> getKeyHandler, bool removeDuplicates,
            bool ignoreWhiteSpaceKeys)
        {
            if (items == null)
                return;
            if (source == null)
                return;
            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            if (ignoreWhiteSpaceKeys)
            {
                foreach (var item in source)
                {
                    var key = getKeyHandler(item);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        key = key.Trim();
                        if ((!removeDuplicates) || (!items.Contains(key)))
                            items.Add(key);
                    }
                }
            }
            else
            {
                foreach (var item in source)
                {
                    var key = getKeyHandler(item);
                    if (key != null)
                    {
                        if ((!removeDuplicates) || (!items.Contains(key)))
                            items.Add(key);
                    }
                }
            }
        }
        public static void AddRange<TKey, TItem>(this SortedDictionary<TKey, TItem> items, IEnumerable<TItem> source, System.Func<TItem, TKey> getKeyHandler, bool removeDuplicates)
        {
            if (items == null)
                return;
            if (source == null)
                return;
            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            foreach (var item in source)
            {
                var key = getKeyHandler(item);
                if (key != null)
                {
                    if ((!removeDuplicates) || (!items.ContainsKey(key)))
                        items.Add(key, item);
                }
            }
        }
        public static void AddRange<TItem>(this SortedDictionary<string, TItem> items, IEnumerable<TItem> source, System.Func<TItem, string> getKeyHandler, bool removeDuplicates,
            bool ignoreWhiteSpaceKeys)
        {
            if (items == null)
                return;
            if (source == null)
                return;
            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            if (ignoreWhiteSpaceKeys)
            {
                foreach (var item in source)
                {
                    var key = getKeyHandler(item);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        key = key.Trim();
                        if ((!removeDuplicates) || (!items.ContainsKey(key)))
                            items.Add(key, item);
                    }
                }
            }
            else
            {
                foreach (var item in source)
                {
                    var key = getKeyHandler(item);
                    if (key != null)
                    {
                        if ((!removeDuplicates) || (!items.ContainsKey(key)))
                            items.Add(key, item);
                    }
                }
            }
        }

        #endregion
        #region Any

        public static bool Any(this System.Collections.IEnumerable items)
        {
            System.Collections.ICollection collection;
            System.Collections.IEnumerator enumerator;
            bool result;

            if (items == null)
                return false;
            collection = items as System.Collections.ICollection;
            if (collection != null)
                return collection.Count > 0;
            enumerator = items.GetEnumerator();
            result = enumerator.MoveNext();
            enumerator.Reset();

            return result;
        }

        #endregion
        #region CastToArray

        public static T[] CastToArray<T>(this System.Collections.IEnumerable items)
        {
            if (items == null)
                return null;
            var list = new List<T>();
            foreach (var item in items)
            {
                if (item is T)
                    list.Add((T)item);
            }
            return list.ToArray();
        }

        #endregion
        #region CastToEnumArray

        public static T[] CastToEnumArray<T>(this System.Collections.IEnumerable items)
        {
            if (items == null)
                return null;
            var list = new List<T>();
            foreach (var item in items)
            {
                if (item is T)
                    list.Add((T)item);
                else
                    list.Add((T)System.Enum.ToObject(typeof(T), item));
            }

            return list.ToArray();
        }

        #endregion
        #region Clear

        public static void Clear(this System.Collections.IEnumerable items)
        {
            var list1 = items as System.Collections.IList;
            if (list1 != null)
                list1.Clear();
        }

        #endregion
        #region Contains

        public static bool Contains(this IEnumerable<string> items, string text, System.StringComparison comparison)
        {
            if (items == null)
                return false;
            if (text == null)
                return false;
            foreach (var item in items)
            {
                if (item.Equals(text, comparison))
                    return true;
            }
            return false;
        }
        public static bool Contains<T>(this IEnumerable<T> items, IEnumerable<T> values)
        {
            if (items == null)
                return false;
            if (values == null)
                return false;
            if (!values.Any())
                return false;
            var itemIndex = ToHashSet<T, T>(items, o => o, true);
            foreach (var value in values)
            {
                if (!itemIndex.Contains(value))
                    return false;
            }
            return true;
        }

        #endregion
        #region ContainsAny

        public static bool ContainsAny<T>(this IEnumerable<T> items, IEnumerable<T> values)
        {
            if (items == null)
                return false;
            if (values == null)
                return false;
            var itemIndex = ToHashSet<T, T>(items, o => o, true);
            foreach (var value in values)
            {
                if (itemIndex.Contains(value))
                    return true;
            }
            return false;
        }

        #endregion
        #region FirstOrDefault

        public static object FirstOrDefault(this System.Collections.IEnumerable items)
        {
            System.Collections.IList collection;
            System.Collections.IEnumerator enumerator;
            object result;

            if (items == null)
                return null;
            collection = items as System.Collections.IList;
            if (collection != null)
            {
                if (collection.Count > 0)
                    return collection[0];
                return null;
            }
            enumerator = items.GetEnumerator();
            if (enumerator.MoveNext())
                result = enumerator.Current;
            else
                result = null;
            enumerator.Reset();

            return result;
        }

        #endregion
        #region GetValue

        public static TValue GetValue<TKey, TValue>(this IDictionary<TKey, TValue> items, TKey? key, TValue defaultValue) where TKey : struct
        {
            TValue value;

            if (items == null)
                return defaultValue;
            if (key == null)
                return defaultValue;
            if (items.TryGetValue(key.Value, out value))
                return value;
            return defaultValue;
        }
        public static TValue GetValue<TKey, TValue>(this IDictionary<TKey, TValue> items, TKey key, TValue defaultValue)
        {
            TValue value;

            if (items == null)
                return defaultValue;
            if (items.TryGetValue(key, out value))
                return value;
            return defaultValue;
        }

        #endregion
        #region IsNullOrEmpty

        public static bool IsNullOrEmpty(this System.Collections.IEnumerable items)
        {
            if (items == null)
                return true;
            if (!items.Any())
                return true;
            return false;
        }

        #endregion
        #region JoinToString

        public static string JoinToString(this System.Collections.IEnumerable items, char separator)
        {
            return JoinToString(items, separator.ToString());
        }
        public static string JoinToString(this System.Collections.IEnumerable items, string separator)
        {
            return JoinToString(items, separator, false);
        }
        public static string JoinToString(this IEnumerable<double> items, char separator)
        {
            return JoinToString(items, separator.ToString());
        }
        public static string JoinToString(this IEnumerable<double> items, string separator)
        {
            return JoinToString(items, separator, false, o =>
            {
                return o.ToString(System.Globalization.CultureInfo.InvariantCulture);
            });
        }
        public static string JoinToString(this System.Collections.IEnumerable items, string separator, bool removeEmptyEntries)
        {
            return JoinToString(items, separator, removeEmptyEntries, o =>
            {
                if (o != null)
                    return o.ToString();
                else
                    return string.Empty;
            });
        }
        public static string JoinToString(this System.Collections.IEnumerable items, string separator, bool removeEmptyEntries, System.Func<object, string> converter)
        {
            if (converter == null)
                throw new System.ArgumentNullException(nameof(converter));

            var firstRow = true;
            var sb = new System.Text.StringBuilder();
            if (items != null)
            {
                foreach (var item in items)
                {
                    var value = converter(item);
                    if ((removeEmptyEntries) && (string.IsNullOrWhiteSpace(value)))
                        continue;
                    if ((!firstRow) && (separator != null))
                        sb.Append(separator);
                    sb.Append(value);
                    firstRow = false;
                }
            }
            return sb.ToString();
        }
        public static string JoinToString<T>(this IEnumerable<T> items, string separator, bool removeEmptyEntries, System.Func<T, string> converter)
        {
            if (converter == null)
                throw new System.ArgumentNullException(nameof(converter));

            var firstRow = true;
            var sb = new System.Text.StringBuilder();
            if (items != null)
            {
                foreach (var item in items)
                {
                    var value = converter(item);
                    if ((removeEmptyEntries) && (string.IsNullOrWhiteSpace(value)))
                        continue;
                    if ((!firstRow) && (separator != null))
                        sb.Append(separator);
                    sb.Append(value);
                    firstRow = false;
                }
            }
            return sb.ToString();
        }

        #endregion
        #region Merge

        public static bool Merge<TItem, TKey>(this IEnumerable<TItem> destination, IEnumerable<TItem> source, System.Func<TItem, TKey> getKeyHandler,
            System.Func<TItem, TItem, bool> mergeItemHandler, System.Action<TItem> addItemHandler, System.Action<TItem> removeItemHandler, bool removeDuplicates)
        {
            return Merge(destination, source, getKeyHandler, mergeItemHandler, addItemHandler, removeItemHandler, removeDuplicates, null);
        }
        public static bool Merge<TItem, TKey>(this IEnumerable<TItem> destination, IEnumerable<TItem> source, System.Func<TItem, TKey> getKeyHandler,
            System.Func<TItem, TItem, bool> mergeItemHandler, System.Action<TItem> addItemHandler, System.Action<TItem> removeItemHandler, bool removeDuplicates, IEqualityComparer<TKey> comparer)
        {
            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            if (destination == null)
                return false;
            if (source == null)
                return false;

            bool updated = false;
            var sourceIndex = ToDictionary(source, o => getKeyHandler(o), removeDuplicates, comparer);
            var deletedItems = new List<TItem>();
            var updatedItemIndex = new HashSet<TKey>();

            // Update & Delete
            foreach (var destinationItem in destination)
            {
                TItem sourceItem;
                var key = getKeyHandler(destinationItem);
                if ((key != null) && (sourceIndex.TryGetValue(key, out sourceItem)))
                {
                    if (mergeItemHandler != null)
                    {
                        if (mergeItemHandler(destinationItem, sourceItem))
                            updated = true;
                    }
                    updatedItemIndex.Add(key);
                }
                else
                {
                    deletedItems.Add(destinationItem);
                    updated = true;
                }
            }
            foreach (var deletedItem in deletedItems)
            {
                if (removeItemHandler != null)
                    removeItemHandler(deletedItem);
                else
                    destination.Remove(deletedItem);
            }

            // Add
            foreach (var sourceItem in sourceIndex.Values)
            {
                var key = getKeyHandler(sourceItem);
                if ((key != null) && (updatedItemIndex.Contains(key)))
                    continue;
                if (addItemHandler != null)
                    addItemHandler(sourceItem);
                else
                    destination.Add(sourceItem);
                updated = true;
            }

            return updated;
        }
        public static bool Merge<TItem>(this IEnumerable<TItem> destination, IEnumerable<TItem> source, System.Func<TItem, string> getKeyHandler,
            System.Func<TItem, TItem, bool> mergeItemHandler, System.Action<TItem> addItemHandler, System.Action<TItem> removeItemHandler,
            bool removeDuplicates, bool ignoreWhiteSpaceKeys)
        {
            return Merge(destination, source, getKeyHandler, mergeItemHandler, addItemHandler, removeItemHandler, removeDuplicates, ignoreWhiteSpaceKeys, null);
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        public static bool Merge<TItem>(this IEnumerable<TItem> destination, IEnumerable<TItem> source, System.Func<TItem, string> getKeyHandler,
            System.Func<TItem, TItem, bool> mergeItemHandler, System.Action<TItem> addItemHandler, System.Action<TItem> removeItemHandler,
            bool removeDuplicates, bool ignoreWhiteSpaceKeys, IEqualityComparer<string> comparer)
        {
            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            if (destination == null)
                return false;
            if (source == null)
                return false;

            bool updated = false;
            var sourceIndex = ToDictionary(source, o => getKeyHandler(o), removeDuplicates, ignoreWhiteSpaceKeys, comparer);
            var deletedItems = new List<TItem>();
            var updatedItemIndex = new HashSet<string>();

            // Update & Delete
            if (ignoreWhiteSpaceKeys)
            {
                foreach (var destinationItem in destination)
                {
                    TItem sourceItem;
                    var key = getKeyHandler(destinationItem);
                    if ((!string.IsNullOrWhiteSpace(key)) && (sourceIndex.TryGetValue(key.Trim(), out sourceItem)))
                    {
                        if (mergeItemHandler != null)
                        {
                            if (mergeItemHandler(destinationItem, sourceItem))
                                updated = true;
                        }
                        updatedItemIndex.Add(key.Trim());
                    }
                    else
                    {
                        deletedItems.Add(destinationItem);
                        updated = true;
                    }
                }
            }
            else
            {
                foreach (var destinationItem in destination)
                {
                    TItem sourceItem;
                    var key = getKeyHandler(destinationItem);
                    if ((key != null) && (sourceIndex.TryGetValue(key, out sourceItem)))
                    {
                        if (mergeItemHandler != null)
                        {
                            if (mergeItemHandler(destinationItem, sourceItem))
                                updated = true;
                        }
                        updatedItemIndex.Add(key);
                    }
                    else
                    {
                        deletedItems.Add(destinationItem);
                        updated = true;
                    }
                }
            }
            foreach (var deletedItem in deletedItems)
            {
                if (removeItemHandler != null)
                    removeItemHandler(deletedItem);
                else
                    destination.Remove(deletedItem);
            }

            // Add
            if (ignoreWhiteSpaceKeys)
            {
                foreach (var sourceItem in sourceIndex.Values)
                {
                    var key = getKeyHandler(sourceItem);
                    if ((!string.IsNullOrWhiteSpace(key)) && (updatedItemIndex.Contains(key.Trim())))
                        continue;
                    if (addItemHandler != null)
                        addItemHandler(sourceItem);
                    else
                        destination.Add(sourceItem);
                    updated = true;
                }
            }
            else
            {
                foreach (var sourceItem in sourceIndex.Values)
                {
                    var key = getKeyHandler(sourceItem);
                    if ((key != null) && (updatedItemIndex.Contains(key)))
                        continue;
                    if (addItemHandler != null)
                        addItemHandler(sourceItem);
                    else
                        destination.Add(sourceItem);
                    updated = true;
                }
            }

            return updated;
        }

        public static bool Merge<TDestination, TSource, TKey>(this IEnumerable<TDestination> destination, IEnumerable<TSource> source,
            System.Func<TDestination, TKey> getDestinationKeyHandler, System.Func<TSource, TKey> getSourceKeyHandler,
            System.Func<TDestination, TSource, bool> mergeItemHandler, System.Action<TSource> addItemHandler, System.Action<TDestination> removeItemHandler,
            bool removeDuplicates)
        {
            return Merge(destination, source, getDestinationKeyHandler, getSourceKeyHandler, mergeItemHandler, addItemHandler, removeItemHandler, removeDuplicates, null);
        }
        public static bool Merge<TDestination, TSource, TKey>(this IEnumerable<TDestination> destination, IEnumerable<TSource> source,
            System.Func<TDestination, TKey> getDestinationKeyHandler, System.Func<TSource, TKey> getSourceKeyHandler,
            System.Func<TDestination, TSource, bool> mergeItemHandler, System.Action<TSource> addItemHandler, System.Action<TDestination> removeItemHandler,
            bool removeDuplicates, IEqualityComparer<TKey> comparer)
        {
            if (getDestinationKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getDestinationKeyHandler));
            if (getSourceKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getSourceKeyHandler));
            if (addItemHandler == null)
                throw new System.ArgumentNullException(nameof(addItemHandler));
            if (destination == null)
                return false;
            if (source == null)
                return false;

            bool updated = false;
            var sourceIndex = ToDictionary(source, o => getSourceKeyHandler(o), removeDuplicates, comparer);
            var deletedItems = new List<TDestination>();
            var updatedItemIndex = new HashSet<TKey>();

            // Update & Delete
            foreach (var destinationItem in destination)
            {
                TSource sourceItem;
                var key = getDestinationKeyHandler(destinationItem);
                if ((key != null) && (sourceIndex.TryGetValue(key, out sourceItem)))
                {
                    if (mergeItemHandler != null)
                    {
                        if (mergeItemHandler(destinationItem, sourceItem))
                            updated = true;
                    }
                    updatedItemIndex.Add(key);
                }
                else
                {
                    deletedItems.Add(destinationItem);
                    updated = true;
                }
            }
            foreach (var deletedItem in deletedItems)
            {
                if (removeItemHandler != null)
                    removeItemHandler(deletedItem);
                else
                    destination.Remove(deletedItem);
            }

            // Add
            foreach (var sourceItem in sourceIndex.Values)
            {
                var key = getSourceKeyHandler(sourceItem);
                if ((key != null) && (updatedItemIndex.Contains(key)))
                    continue;
                addItemHandler(sourceItem);
                updated = true;
            }

            return updated;
        }
        public static bool Merge<TDestination, TSource>(this IEnumerable<TDestination> destination, IEnumerable<TSource> source,
            System.Func<TDestination, string> getDestinationKeyHandler, System.Func<TSource, string> getSourceKeyHandler,
            System.Func<TDestination, TSource, bool> mergeItemHandler, System.Action<TSource> addItemHandler, System.Action<TDestination> removeItemHandler,
            bool removeDuplicates, bool ignoreWhiteSpaceKeys)
        {
            return Merge(destination, source, getDestinationKeyHandler, getSourceKeyHandler, mergeItemHandler, addItemHandler, removeItemHandler, removeDuplicates,
                ignoreWhiteSpaceKeys, null);
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        public static bool Merge<TDestination, TSource>(this IEnumerable<TDestination> destination, IEnumerable<TSource> source,
            System.Func<TDestination, string> getDestinationKeyHandler, System.Func<TSource, string> getSourceKeyHandler,
            System.Func<TDestination, TSource, bool> mergeItemHandler, System.Action<TSource> addItemHandler, System.Action<TDestination> removeItemHandler,
            bool removeDuplicates, bool ignoreWhiteSpaceKeys, IEqualityComparer<string> comparer)
        {
            if (getDestinationKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getDestinationKeyHandler));
            if (getSourceKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getSourceKeyHandler));
            if (addItemHandler == null)
                throw new System.ArgumentNullException(nameof(addItemHandler));
            if (destination == null)
                return false;
            if (source == null)
                return false;

            bool updated = false;
            var sourceIndex = ToDictionary(source, o => getSourceKeyHandler(o), removeDuplicates, ignoreWhiteSpaceKeys, comparer);
            var deletedItems = new List<TDestination>();
            var updatedItemIndex = new HashSet<string>();

            // Update & Delete
            if (ignoreWhiteSpaceKeys)
            {
                foreach (var destinationItem in destination)
                {
                    TSource sourceItem;
                    var key = getDestinationKeyHandler(destinationItem);
                    if ((!string.IsNullOrWhiteSpace(key)) && (sourceIndex.TryGetValue(key.Trim(), out sourceItem)))
                    {
                        if (mergeItemHandler != null)
                        {
                            if (mergeItemHandler(destinationItem, sourceItem))
                                updated = true;
                        }
                        updatedItemIndex.Add(key.Trim());
                    }
                    else
                    {
                        deletedItems.Add(destinationItem);
                        updated = true;
                    }
                }
            }
            else
            {
                foreach (var destinationItem in destination)
                {
                    TSource sourceItem;
                    var key = getDestinationKeyHandler(destinationItem);
                    if ((key != null) && (sourceIndex.TryGetValue(key, out sourceItem)))
                    {
                        if (mergeItemHandler != null)
                        {
                            if (mergeItemHandler(destinationItem, sourceItem))
                                updated = true;
                        }
                        updatedItemIndex.Add(key);
                    }
                    else
                    {
                        deletedItems.Add(destinationItem);
                        updated = true;
                    }
                }
            }
            foreach (var deletedItem in deletedItems)
            {
                if (removeItemHandler != null)
                    removeItemHandler(deletedItem);
                else
                    destination.Remove(deletedItem);
            }

            // Add
            if (ignoreWhiteSpaceKeys)
            {
                foreach (var sourceItem in sourceIndex.Values)
                {
                    var key = getSourceKeyHandler(sourceItem);
                    if ((!string.IsNullOrWhiteSpace(key)) && (updatedItemIndex.Contains(key.Trim())))
                        continue;
                    addItemHandler(sourceItem);
                    updated = true;
                }
            }
            else
            {
                foreach (var sourceItem in sourceIndex.Values)
                {
                    var key = getSourceKeyHandler(sourceItem);
                    if ((key != null) && (updatedItemIndex.Contains(key)))
                        continue;
                    addItemHandler(sourceItem);
                    updated = true;
                }
            }

            return updated;
        }

        #endregion
        #region Remove

        public static void Remove(this System.Collections.IEnumerable items, object item)
        {
            var list1 = items as System.Collections.IList;
            if (list1 != null)
                list1.Remove(item);
        }

        #endregion
        #region ToDictionary

        public static Dictionary<TKey, TItem> ToDictionary<TKey, TItem>(this IEnumerable<TItem> items, System.Func<TItem, TKey> getKeyHandler, bool removeDuplicates)
        {
            return ToDictionary(items, getKeyHandler, removeDuplicates, null);
        }
        public static Dictionary<TKey, TItem> ToDictionary<TKey, TItem>(this IEnumerable<TItem> items, System.Func<TItem, TKey> getKeyHandler, bool removeDuplicates, IEqualityComparer<TKey> comparer)
        {
            Dictionary<TKey, TItem> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException("getKeyHandler");
            if (items == null)
                return null;
            if (comparer != null)
                list = new Dictionary<TKey, TItem>(comparer);
            else
                list = new Dictionary<TKey, TItem>();
            AddRange(list, items, getKeyHandler, removeDuplicates);
            return list;
        }
        public static Dictionary<string, TItem> ToDictionary<TItem>(this IEnumerable<TItem> items, System.Func<TItem, string> getKeyHandler, bool removeDuplicates, bool ignoreWhiteSpaceKeys)
        {
            return ToDictionary(items, getKeyHandler, removeDuplicates, ignoreWhiteSpaceKeys, null);
        }
        public static Dictionary<string, TItem> ToDictionary<TItem>(this IEnumerable<TItem> items, System.Func<TItem, string> getKeyHandler, bool removeDuplicates, bool ignoreWhiteSpaceKeys,
            IEqualityComparer<string> comparer)
        {
            Dictionary<string, TItem> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            if (items == null)
                return null;

            if (comparer != null)
                list = new Dictionary<string, TItem>(comparer);
            else
                list = new Dictionary<string, TItem>();
            AddRange(list, items, getKeyHandler, removeDuplicates, ignoreWhiteSpaceKeys);
            return list;
        }

        #endregion
        #region ToDictionaryCollection

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public static Dictionary<TKey, System.Collections.ObjectModel.Collection<TItem>> ToDictionaryCollection<TKey, TItem>(this IEnumerable<TItem> items, System.Func<TItem, TKey> getKeyHandler)
        {
            return ToDictionaryCollection(items, getKeyHandler, null);
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public static Dictionary<TKey, System.Collections.ObjectModel.Collection<TItem>> ToDictionaryCollection<TKey, TItem>(this IEnumerable<TItem> items, System.Func<TItem, TKey> getKeyHandler,
            IEqualityComparer<TKey> comparer)
        {
            Dictionary<TKey, System.Collections.ObjectModel.Collection<TItem>> index;
            System.Collections.ObjectModel.Collection<TItem> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException("getKeyHandler");
            if (items == null)
                return null;
            if (comparer != null)
                index = new Dictionary<TKey, System.Collections.ObjectModel.Collection<TItem>>(comparer);
            else
                index = new Dictionary<TKey, System.Collections.ObjectModel.Collection<TItem>>();
            foreach (var item in items)
            {
                var value = getKeyHandler(item);
                if (value != null)
                {
                    if (!index.TryGetValue(value, out list))
                    {
                        list = new System.Collections.ObjectModel.Collection<TItem>();
                        index.Add(value, list);
                    }
                    list.Add(item);
                }
            }
            return index;
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public static Dictionary<string, System.Collections.ObjectModel.Collection<TItem>> ToDictionaryCollection<TItem>(this IEnumerable<TItem> items, System.Func<TItem, string> getKeyHandler,
            bool ignoreWhiteSpaceKeys)
        {
            return ToDictionaryCollection(items, getKeyHandler, ignoreWhiteSpaceKeys, null);
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public static Dictionary<string, System.Collections.ObjectModel.Collection<TItem>> ToDictionaryCollection<TItem>(this IEnumerable<TItem> items, System.Func<TItem, string> getKeyHandler,
            bool ignoreWhiteSpaceKeys, IEqualityComparer<string> comparer)
        {
            Dictionary<string, System.Collections.ObjectModel.Collection<TItem>> index;
            System.Collections.ObjectModel.Collection<TItem> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException("getKeyHandler");
            if (items == null)
                return null;
            if (comparer != null)
                index = new Dictionary<string, System.Collections.ObjectModel.Collection<TItem>>(comparer);
            else
                index = new Dictionary<string, System.Collections.ObjectModel.Collection<TItem>>();
            if (ignoreWhiteSpaceKeys)
            {
                foreach (var item in items)
                {
                    var key = getKeyHandler(item);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        key = key.Trim();
                        if (!index.TryGetValue(key, out list))
                        {
                            list = new System.Collections.ObjectModel.Collection<TItem>();
                            index.Add(key, list);
                        }
                        list.Add(item);
                    }
                }
            }
            else
            {
                foreach (var item in items)
                {
                    var key = getKeyHandler(item);
                    if (key != null)
                    {
                        if (!index.TryGetValue(key, out list))
                        {
                            list = new System.Collections.ObjectModel.Collection<TItem>();
                            index.Add(key, list);
                        }
                        list.Add(item);
                    }
                }
            }
            return index;
        }

        #endregion
        #region ToSortedDictionary

        public static SortedDictionary<TKey, TItem> ToSortedDictionary<TKey, TItem>(this IEnumerable<TItem> items, System.Func<TItem, TKey> getKeyHandler, bool removeDuplicates)
        {
            return ToSortedDictionary(items, getKeyHandler, removeDuplicates, null);
        }
        public static SortedDictionary<TKey, TItem> ToSortedDictionary<TKey, TItem>(this IEnumerable<TItem> items, System.Func<TItem, TKey> getKeyHandler, bool removeDuplicates,
            IComparer<TKey> comparer)
        {
            SortedDictionary<TKey, TItem> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException("getKeyHandler");
            if (items == null)
                return null;
            if (comparer != null)
                list = new SortedDictionary<TKey, TItem>(comparer);
            else
                list = new SortedDictionary<TKey, TItem>();
            AddRange(list, items, getKeyHandler, removeDuplicates);
            return list;
        }
        public static SortedDictionary<string, TItem> ToSortedDictionary<TItem>(this IEnumerable<TItem> items, System.Func<TItem, string> getKeyHandler, bool removeDuplicates,
            bool ignoreWhiteSpaceKeys)
        {
            return ToSortedDictionary(items, getKeyHandler, removeDuplicates, ignoreWhiteSpaceKeys, null);
        }
        public static SortedDictionary<string, TItem> ToSortedDictionary<TItem>(this IEnumerable<TItem> items, System.Func<TItem, string> getKeyHandler, bool removeDuplicates,
            bool ignoreWhiteSpaceKeys,
            IComparer<string> comparer)
        {
            SortedDictionary<string, TItem> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            if (items == null)
                return null;

            if (comparer != null)
                list = new SortedDictionary<string, TItem>(comparer);
            else
                list = new SortedDictionary<string, TItem>();
            AddRange(list, items, getKeyHandler, removeDuplicates, ignoreWhiteSpaceKeys);
            return list;
        }

        #endregion
        #region ToSortedDictionaryCollection

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public static SortedDictionary<TKey, System.Collections.ObjectModel.Collection<TItem>> ToSortedDictionaryCollection<TKey, TItem>(this IEnumerable<TItem> items,
            System.Func<TItem, TKey> getKeyHandler)
        {
            return ToSortedDictionaryCollection(items, getKeyHandler, null);
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public static SortedDictionary<TKey, System.Collections.ObjectModel.Collection<TItem>> ToSortedDictionaryCollection<TKey, TItem>(this IEnumerable<TItem> items,
            System.Func<TItem, TKey> getKeyHandler, IComparer<TKey> comparer)
        {
            SortedDictionary<TKey, System.Collections.ObjectModel.Collection<TItem>> index;
            System.Collections.ObjectModel.Collection<TItem> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException("getKeyHandler");
            if (items == null)
                return null;
            if (comparer != null)
                index = new SortedDictionary<TKey, System.Collections.ObjectModel.Collection<TItem>>(comparer);
            else
                index = new SortedDictionary<TKey, System.Collections.ObjectModel.Collection<TItem>>();
            foreach (var item in items)
            {
                var value = getKeyHandler(item);
                if (value != null)
                {
                    if (!index.TryGetValue(value, out list))
                    {
                        list = new System.Collections.ObjectModel.Collection<TItem>();
                        index.Add(value, list);
                    }
                    list.Add(item);
                }
            }
            return index;
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public static SortedDictionary<string, System.Collections.ObjectModel.Collection<TItem>> ToSortedDictionaryCollection<TItem>(this IEnumerable<TItem> items,
            System.Func<TItem, string> getKeyHandler, bool ignoreWhiteSpaceKeys)
        {
            return ToSortedDictionaryCollection(items, getKeyHandler, ignoreWhiteSpaceKeys, null);
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public static SortedDictionary<string, System.Collections.ObjectModel.Collection<TItem>> ToSortedDictionaryCollection<TItem>(this IEnumerable<TItem> items,
            System.Func<TItem, string> getKeyHandler, bool ignoreWhiteSpaceKeys, IComparer<string> comparer)
        {
            SortedDictionary<string, System.Collections.ObjectModel.Collection<TItem>> index;
            System.Collections.ObjectModel.Collection<TItem> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException("getKeyHandler");
            if (items == null)
                return null;
            if (comparer != null)
                index = new SortedDictionary<string, System.Collections.ObjectModel.Collection<TItem>>(comparer);
            else
                index = new SortedDictionary<string, System.Collections.ObjectModel.Collection<TItem>>();
            if (ignoreWhiteSpaceKeys)
            {
                foreach (var item in items)
                {
                    var key = getKeyHandler(item);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        key = key.Trim();
                        if (!index.TryGetValue(key, out list))
                        {
                            list = new System.Collections.ObjectModel.Collection<TItem>();
                            index.Add(key, list);
                        }
                        list.Add(item);
                    }
                }
            }
            else
            {
                foreach (var item in items)
                {
                    var key = getKeyHandler(item);
                    if (key != null)
                    {
                        if (!index.TryGetValue(key, out list))
                        {
                            list = new System.Collections.ObjectModel.Collection<TItem>();
                            index.Add(key, list);
                        }
                        list.Add(item);
                    }
                }
            }
            return index;
        }

        #endregion
        #region ToEnumArray

        public static T[] ToEnumArray<T>(this IEnumerable<object> items)
        {
            List<T> list;
            T value;

            if (items == null)
                return null;

            list = new List<T>();
            foreach (var item in items)
            {
                if (item == null)
                    continue;
                if (item is T)
                    value = (T)item;
                else
                    value = (T)System.Enum.Parse(typeof(T), item.ToString(null), true);

                list.Add(value);
            }

            return list.ToArray();
        }
        public static T[] ToEnumArray<T>(this IEnumerable<string> items)
        {
            List<T> list;
            T value;

            if (items == null)
                return null;

            list = new List<T>();
            foreach (var item in items)
            {
                value = (T)System.Enum.Parse(typeof(T), item, true);
                list.Add(value);
            }

            return list.ToArray();
        }

        #endregion
        #region ToHashSet

        public static HashSet<TKey> ToHashSet<TKey, TItem>(this IEnumerable<TItem> items, System.Func<TItem, TKey> getKeyHandler, bool removeDuplicates)
        {
            return ToHashSet(items, getKeyHandler, removeDuplicates, null);
        }
        public static HashSet<TKey> ToHashSet<TKey, TItem>(this IEnumerable<TItem> items, System.Func<TItem, TKey> getKeyHandler, bool removeDuplicates, IEqualityComparer<TKey> comparer)
        {
            HashSet<TKey> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            if (items == null)
                return null;
            if (comparer != null)
                list = new HashSet<TKey>(comparer);
            else
                list = new HashSet<TKey>();
            AddRange(list, items, getKeyHandler, removeDuplicates);
            return list;
        }
        public static HashSet<string> ToHashSet<TItem>(this IEnumerable<TItem> items, System.Func<TItem, string> getKeyHandler, bool removeDuplicates, bool ignoreWhiteSpaceKeys)
        {
            return ToHashSet(items, getKeyHandler, removeDuplicates, ignoreWhiteSpaceKeys, null);
        }
        public static HashSet<string> ToHashSet<TItem>(this IEnumerable<TItem> items, System.Func<TItem, string> getKeyHandler, bool removeDuplicates, bool ignoreWhiteSpaceKeys,
            IEqualityComparer<string> comparer)
        {
            HashSet<string> list;

            if (getKeyHandler == null)
                throw new System.ArgumentNullException(nameof(getKeyHandler));
            if (items == null)
                return null;
            if (comparer != null)
                list = new HashSet<string>(comparer);
            else
                list = new HashSet<string>();
            AddRange(list, items, getKeyHandler, removeDuplicates, ignoreWhiteSpaceKeys);
            return list;
        }

        #endregion
        #region ToDoubleArray

        public static double[] ToDoubleArray(this IEnumerable<object> items)
        {
            if (items == null)
                return null;
            var list = new List<double>();
            foreach (var item in items)
            {
                var value = item.ToNullableDouble();
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }
        public static double[] ToDoubleArray(this IEnumerable<string> items)
        {
            if (items == null)
                return null;
            var list = new List<double>();
            foreach (var item in items)
            {
                var value = item.ToNullableDouble();
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }
        public static double[] ToDoubleArray(this IEnumerable<string> items, System.Globalization.NumberStyles style, System.IFormatProvider provider)
        {
            if (items == null)
                return null;
            var list = new List<double>();
            foreach (var item in items)
            {
                var value = item.ToNullableDouble(style, provider);
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }

        #endregion
        #region ToGuidArray

        public static System.Guid[] ToGuidArray(this IEnumerable<object> items)
        {
            if (items == null)
                return null;
            var list = new List<System.Guid>();
            foreach (var item in items)
            {
                var value = item.ToNullableGuid();
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }
        public static System.Guid[] ToGuidArray(this IEnumerable<string> items)
        {
            if (items == null)
                return null;
            var list = new List<System.Guid>();
            foreach (var item in items)
            {
                var value = item.ToNullableGuid();
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }

        #endregion
        #region ToInt32Array

        public static int[] ToInt32Array(this IEnumerable<object> items)
        {
            if (items == null)
                return null;
            var list = new List<int>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt32();
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }
        public static int[] ToInt32Array(this IEnumerable<string> items)
        {
            if (items == null)
                return null;
            var list = new List<int>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt32();
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }
        public static int[] ToInt32Array(this IEnumerable<string> items, System.Globalization.NumberStyles style, System.IFormatProvider provider)
        {
            if (items == null)
                return null;
            var list = new List<int>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt32(style, provider);
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }

        #endregion
        #region ToInt32HashSet

        public static HashSet<long> ToInt32HashSet(this IEnumerable<object> items, bool removeDuplicates)
        {
            if (items == null)
                return null;
            var list = new HashSet<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt32();
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }
        public static HashSet<long> ToInt32HashSet(this IEnumerable<string> items, bool removeDuplicates)
        {
            if (items == null)
                return null;
            var list = new HashSet<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt32();
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }
        public static HashSet<long> ToInt32HashSet(this IEnumerable<string> items, bool removeDuplicates, System.Globalization.NumberStyles style, System.IFormatProvider provider)
        {
            if (items == null)
                return null;
            var list = new HashSet<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt32(style, provider);
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }

        #endregion
        #region ToInt32List

        public static List<long> ToInt32List(this IEnumerable<object> items, bool removeDuplicates)
        {
            if (items == null)
                return null;
            var list = new List<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt32();
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }
        public static List<long> ToInt32List(this IEnumerable<string> items, bool removeDuplicates)
        {
            if (items == null)
                return null;
            var list = new List<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt32();
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }
        public static List<long> ToInt32List(this IEnumerable<string> items, bool removeDuplicates, System.Globalization.NumberStyles style, System.IFormatProvider provider)
        {
            if (items == null)
                return null;
            var list = new List<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt32(style, provider);
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }

        #endregion
        #region ToInt64Array

        public static long[] ToInt64Array(this IEnumerable<object> items)
        {
            if (items == null)
                return null;
            var list = new List<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt64();
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }
        public static long[] ToInt64Array(this IEnumerable<string> items)
        {
            if (items == null)
                return null;
            var list = new List<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt64();
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }
        public static long[] ToInt64Array(this IEnumerable<string> items, System.Globalization.NumberStyles style, System.IFormatProvider provider)
        {
            if (items == null)
                return null;
            var list = new List<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt64(style, provider);
                if (value != null)
                    list.Add(value.Value);
            }
            return list.ToArray();
        }

        #endregion
        #region ToInt64HashSet

        public static HashSet<long> ToInt64HashSet(this IEnumerable<object> items, bool removeDuplicates)
        {
            if (items == null)
                return null;
            var list = new HashSet<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt64();
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }
        public static HashSet<long> ToInt64HashSet(this IEnumerable<string> items, bool removeDuplicates)
        {
            if (items == null)
                return null;
            var list = new HashSet<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt64();
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }
        public static HashSet<long> ToInt64HashSet(this IEnumerable<string> items, bool removeDuplicates, System.Globalization.NumberStyles style, System.IFormatProvider provider)
        {
            if (items == null)
                return null;
            var list = new HashSet<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt64(style, provider);
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }

        #endregion
        #region ToInt64List

        public static List<long> ToInt64List(this IEnumerable<object> items, bool removeDuplicates)
        {
            if (items == null)
                return null;
            var list = new List<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt64();
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }
        public static List<long> ToInt64List(this IEnumerable<string> items, bool removeDuplicates)
        {
            if (items == null)
                return null;
            var list = new List<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt64();
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }
        public static List<long> ToInt64List(this IEnumerable<string> items, bool removeDuplicates, System.Globalization.NumberStyles style, System.IFormatProvider provider)
        {
            if (items == null)
                return null;
            var list = new List<long>();
            foreach (var item in items)
            {
                var value = item.ToNullableInt64(style, provider);
                if ((value != null) && ((!removeDuplicates) || (!list.Contains(value.Value))))
                    list.Add(value.Value);
            }
            return list;
        }

        #endregion
        #region ToStringArray

        public static string[] ToStringArray(this IEnumerable<int> items)
        {
            if (items == null)
                return null;
            var list = new List<string>();
            foreach (var item in items)
                list.Add(item.ToString(System.Globalization.CultureInfo.InvariantCulture));
            return list.ToArray();
        }
        public static string[] ToStringArray(this IEnumerable<long> items)
        {
            if (items == null)
                return null;
            var list = new List<string>();
            foreach (var item in items)
                list.Add(item.ToString(System.Globalization.CultureInfo.InvariantCulture));
            return list.ToArray();
        }
        public static string[] ToStringArray(this IEnumerable<System.Guid> items)
        {
            if (items == null)
                return null;
            var list = new List<string>();
            foreach (var item in items)
                list.Add(item.ToString());
            return list.ToArray();
        }
        public static string[] ToStringArray(this IEnumerable<object> items, bool removeEmptyEntries)
        {
            if (items == null)
                return null;
            var list = new List<string>();
            foreach (var item in items)
            {
                var value = item.ToString(null);
                if ((removeEmptyEntries) && (string.IsNullOrWhiteSpace(value)))
                    continue;
                list.Add(value);
            }
            return list.ToArray();
        }
        public static string[] ToStringArray<TItem>(this IEnumerable<TItem> items, bool removeEmptyEntries, System.Func<TItem, string> getStringHandler)
        {
            string value;

            if (items == null)
                return null;
            var list = new List<string>();
            foreach (var item in items)
            {
                if (getStringHandler != null)
                    value = getStringHandler(item);
                else
                    value = item.ToString(null);
                if ((removeEmptyEntries) && (string.IsNullOrWhiteSpace(value)))
                    continue;
                list.Add(value);
            }
            return list.ToArray();
        }

        #endregion
    }
}
